// BWSetting.cpp: implementation of the CBWSetting class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BuildWiz.h"
#include "BWSetting.h"
#include "INI.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBWSetting::CBWSetting()
{
	TCHAR		szTmp[MAX_PATH] = {0};

	GetCurrentDirectory(MAX_PATH, szTmp);

	m_strIni.Format("%s\\BuildWiz.xml", szTmp);

	ZeroMemory (&m_stuBWS_COMM, sizeof(STU_BWS_COMM));
}


CBWSetting::CBWSetting(LPCSTR	strFname)
{
	m_strIni = strFname;
}


CBWSetting::~CBWSetting()
{

}


BOOL CBWSetting::InitXMLSettings()
{
	CMarkup		objXml;
	CString		csMsg, csError, strSection, strEntry;

	BOOL bResult = objXml.Load(m_strIni);

	csError = MCD_2PCSZ(objXml.GetError());
	if ( !bResult )
	{
		char		szMsg[1024] = {0};

		sprintf (szMsg, "Load %s failed for the following reason:     \n\n%s     ",
				m_strIni,
				csError);

		MessageBox (NULL, szMsg, "BuildWiz", MB_OK | MB_ICONERROR);
		return FALSE;
	}

	STU_BWS_ITEM		bwsItem;
	m_arrBWItems.RemoveAll();

	objXml.ResetPos();

	//
	// get common settings.
	//
	objXml.FindChildElem(_T("common"));
	objXml.IntoElem();

	// Project name 
	if ( objXml.FindChildElem(_T("Project")) )
		strEntry = objXml.GetChildData();
	else
		strEntry = "Build Wizard 2009";
	
	strcpy(m_stuBWS_COMM.szPrjName, strEntry);

	// Author
	if ( objXml.FindChildElem(_T("Author")) )
		strEntry = objXml.GetChildData();
	else
		strEntry = "by Y.Volta Tang";
	
	strcpy(m_stuBWS_COMM.szAuthor, strEntry);


	// Comments
	if ( objXml.FindChildElem(_T("Comments")) )
		strEntry = objXml.GetChildData();
	else
		strEntry = "Please provide me a BuildWiz.xml file.";
	
	strcpy(m_stuBWS_COMM.szComments, strEntry);

	// BaseDir
	if ( objXml.FindChildElem(_T("BaseDir")) )
		strEntry = objXml.GetChildAttrib(_T("value"));
	else
		strEntry = "";

	// added for best experience. 2008-05-16
	if(strEntry.CompareNoCase("{PWD}") == 0)
	{
		TCHAR		szTmp[MAX_PATH] = {0};
		
		GetCurrentDirectory(MAX_PATH, szTmp);
		
		strEntry.Format("%s", szTmp);
	}
	else if (strEntry.IsEmpty())
	{	// if there is no path, use the program path.
		
		GetAppDir(strEntry);		
	}
	strcpy(m_stuBWS_COMM.szBaseDir, strEntry);

	
	// Log file by using SQLite
	if ( objXml.FindChildElem(_T("LogFile")) )
		strEntry = objXml.GetChildAttrib(_T("file"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szLogFile, strEntry);


	// Inc Dir
	if ( objXml.FindChildElem(_T("IncDir")) )
		strEntry = objXml.GetChildAttrib(_T("value"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szIncDir, strEntry);


	// Lib Dir
	if ( objXml.FindChildElem(_T("LibDir")) )
		strEntry = objXml.GetChildAttrib(_T("value"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szLibDir, strEntry);


	// Exe Dir
	if ( objXml.FindChildElem(_T("ExeDir")) )
		strEntry = objXml.GetChildAttrib(_T("value"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szExeDir, strEntry);

	
	// PreCompile
	if ( objXml.FindChildElem(_T("PreCompile")) )
		strEntry = objXml.GetChildAttrib(_T("command"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szPreCompile, strEntry);
	
	// PostCompile
	if ( objXml.FindChildElem(_T("PostCompile")) )
		strEntry = objXml.GetChildAttrib(_T("command"));
	else
		strEntry = "";
	PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szPostCompile, strEntry);
	

	//
	// find all items one by one.
	//
	objXml.ResetPos();
	m_stuBWS_COMM.nItems = 0;

	while ( objXml.FindChildElem(_T("item")) )
	{
		// Is this the right section?
		strSection = objXml.GetChildAttrib(_T("name"));

		if (strSection.IsEmpty())
			continue;

		objXml.IntoElem();

		memset(&bwsItem, 0x0, sizeof(STU_BWS_ITEM));
		
		// components
		strcpy(bwsItem.szComponent, strSection);


		// selection 
		if ( objXml.FindChildElem(_T("select")) )
			strEntry = objXml.GetChildData();
		else
			strEntry = "no";

		strcpy(bwsItem.szStatus, strEntry);


		// Comments 
		if ( objXml.FindChildElem(_T("comments")) )
			strEntry = objXml.GetChildData();
		else
			strEntry = strSection;
		
		strcpy(bwsItem.szComments, strEntry);
		

		// command 
		if ( objXml.FindChildElem(_T("build")) )
			strEntry = objXml.GetChildAttrib("command");
		else
			strEntry = "echo.";
		
		PatchVarString(strEntry, m_stuBWS_COMM.szBaseDir);
		strcpy(bwsItem.szCmdl, strEntry);
		
		m_arrBWItems.Add(bwsItem);	
		
		m_stuBWS_COMM.nItems ++;

		objXml.OutOfElem();
	}	

	return TRUE;
}


BOOL CBWSetting::InitSettings()
{
	CIniReader		objIni;
	CString			strTemp, strItem;

	objIni.setINIFileName(m_strIni);

	// [ Common ] Sections
	// Project name
	strTemp = objIni.getKeyValue("Project", "Common");		
	if(strlen(strTemp) <= 0)
		strcpy(m_stuBWS_COMM.szPrjName, "Build Wizard 2009");
	else
		strcpy(m_stuBWS_COMM.szPrjName, strTemp);
	
	// Author
	strTemp = objIni.getKeyValue("Author", "Common");		
	if(strlen(strTemp) <= 0)
		strcpy(m_stuBWS_COMM.szAuthor, "by Y.Volta Tang");
	else
		strcpy(m_stuBWS_COMM.szAuthor, strTemp);

	// Items
	strTemp = objIni.getKeyValue("Items", "Common");		
	m_stuBWS_COMM.nItems = atoi(strTemp);

	// Comments
	strTemp = objIni.getKeyValue("Comments", "Common");	
	if(strlen(strTemp) <= 0)
		strcpy(m_stuBWS_COMM.szComments, "Please provide me a BuildWiz.ini file.");
	else
		strcpy(m_stuBWS_COMM.szComments, strTemp);
	
	// Log file by using SQLite
	strTemp = objIni.getKeyValue("LogFile", "Common");	
	if(strlen(strTemp) <= 0)
		strcpy(m_stuBWS_COMM.szLogFile, "");
	else
		strcpy(m_stuBWS_COMM.szLogFile, strTemp);


	// BaseDir
	strTemp = objIni.getKeyValue("BaseDir", "Common");		
	
	// added for best experience. 2008-05-16
	if(strTemp.CompareNoCase("{PWD}") == 0)
	{
		TCHAR		szTmp[MAX_PATH] = {0};
		
		GetCurrentDirectory(MAX_PATH, szTmp);
		
		strTemp.Format("%s", szTmp);
	}
	else if (strTemp.IsEmpty())
	{	// if there is no path, use the program path.

		GetAppDir(strTemp);		
	}

	// -end
	strcpy(m_stuBWS_COMM.szBaseDir, strTemp);


	// PreCompile
	strTemp = objIni.getKeyValue("PreCompile", "Common");
	PatchVarString(strTemp, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szPreCompile, strTemp);

	// PostCompile
	strTemp = objIni.getKeyValue("PostCompile", "Common");
	PatchVarString(strTemp, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szPostCompile, strTemp);
	
	// Inc Dir
	strTemp = objIni.getKeyValue("IncDir", "Common");
	PatchVarString(strTemp, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szIncDir, strTemp);

	// Lib Dir
	strTemp = objIni.getKeyValue("LibDir", "Common");
	PatchVarString(strTemp, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szLibDir, strTemp);

	// Exe Dir
	strTemp = objIni.getKeyValue("ExeDir", "Common");
	PatchVarString(strTemp, m_stuBWS_COMM.szBaseDir);
	strcpy(m_stuBWS_COMM.szExeDir, strTemp);


	//
	STU_BWS_ITEM		bwsItem;
	m_arrBWItems.RemoveAll();
	
	for(int i = 1; i<= m_stuBWS_COMM.nItems; i ++ )
	{
		strTemp.Format("Item%d", i);
		
		if(!objIni.sectionExists(strTemp))
			continue;

		memset(&bwsItem, 0x0, sizeof(STU_BWS_ITEM));

		// Component
		strItem = objIni.getKeyValue("Component", strTemp);
		strcpy(bwsItem.szComponent, strItem);

		// Comments
		strItem = objIni.getKeyValue("Comments", strTemp);
		strcpy(bwsItem.szComments, strItem);

		// Command
		strItem = objIni.getKeyValue("Command", strTemp);
		PatchVarString(strItem, m_stuBWS_COMM.szBaseDir);
		strcpy(bwsItem.szCmdl, strItem);

		// Status
		strItem = objIni.getKeyValue("Select", strTemp);
		strcpy(bwsItem.szStatus, strItem);
		
		m_arrBWItems.Add(bwsItem);
	}


	return TRUE;
}

void CBWSetting::UpdateItemStatus(LPCTSTR strItem, LPCTSTR strStatus)
{
	CIniReader		objIni;
		
	objIni.setINIFileName(m_strIni);
	
	objIni.setKey(strStatus, "Select", strItem);
}

void CBWSetting::UpdateXmlItemStatus(UINT nItem, LPCTSTR strStatus)
{
	CMarkup				objXml;
	CString				csMsg, csError, strSection, strEntry;
	STU_BWS_ITEM		bwsItem;

	if (nItem > m_arrBWItems.GetSize())
		return;

	memset(&bwsItem, 0x0, sizeof(STU_BWS_ITEM));
	bwsItem = m_arrBWItems.GetAt(nItem);

	// check for the status, if status has not changed, skip.
	strEntry.Format("%s", bwsItem.szStatus);
	if(strEntry.CompareNoCase(strStatus) == 0)
		return;

	BOOL bResult = objXml.Load(m_strIni);
	
	csError = MCD_2PCSZ(objXml.GetError());
	if ( !bResult )
	{
		TRACE("Load file failed.\n");
		return;
	}
	
	objXml.ResetPos();
	while ( objXml.FindChildElem(_T("Item")) )
	{
		// Is this the right section?
		strSection = objXml.GetChildAttrib(_T("name"));
		
		if (strSection.IsEmpty())
			continue;
		
		objXml.IntoElem();
		
		if (strSection.CompareNoCase(bwsItem.szComponent) == 0)
		{
			if ( objXml.FindChildElem(_T("select")) )
			{
				objXml.SetChildData(strStatus);

				objXml.Save(m_strIni);
				return;
			}
		}
		
		objXml.OutOfElem();
	}

}


void CBWSetting::PatchVarString(CString &strDst, LPCTSTR strVar)
{	
	strDst.MakeLower();
	strDst.Replace("%basedir%", strVar);
}

void CBWSetting::GetAppDir(CString &strPath)
{
    TCHAR   sDrive[_MAX_DRIVE] = {0};  
    TCHAR   sDir[_MAX_DIR] = {0};
    TCHAR   sFilename[_MAX_FNAME] = {0}, Filename[_MAX_FNAME] = {0};  
    TCHAR   sExt[_MAX_EXT] = {0};  
	
    GetModuleFileName(AfxGetInstanceHandle(), Filename, _MAX_PATH);
	
    _tsplitpath(Filename, sDrive, sDir, sFilename, sExt);  
	
    CString   homeDir(CString(sDrive)   +   CString(sDir));  
    
	int   nLen   =   homeDir.GetLength();  
    
	if(homeDir.GetAt(nLen-1)   !=   _T('\\'))  
		homeDir   +=   _T('\\');  
	
	strPath = homeDir;
}



void CBWSetting::SetSettingFile(LPCTSTR lpstrFile)
{
	m_strIni = lpstrFile;
}
